/**********************************************************************
 *
 * PostGIS - Spatial Types for PostgreSQL
 * http://postgis.net
 *
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU General Public Licence. See the COPYING file.
 *
 **********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CUnit/Basic.h"

#include "cu_tester.h"
#include "liblwgeom.h"

extern LWGEOM *lwgeom_sfcgal_noop(const LWGEOM *geom_in);

static void
test_sfcgal_noop(void)
{
	size_t i;

	char *ewkt[] = {
	    "POINT(0 0.2)",
	    "LINESTRING(-1 -1,-1 2.5,2 2,2 -1)",
	    "TRIANGLE((0 0,-1 1,0 -1,0 0))",
	    "MULTIPOINT(0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9)",
	    "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))",
	    "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))",
	    "POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))",
	    "SRID=4326;POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))",
	    "SRID=4326;POLYGON((-1 -1 1,-1 2.5 1,2 2 2,2 -1 2,-1 -1 2),(0 0 1,0 1 1,1 1 1,1 0 2,0 0 2))",
	    "SRID=4326;POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))",
	    "SRID=100000;POLYGON((-1 -1 3,-1 2.5 3,2 2 3,2 -1 3,-1 -1 3),(0 0 3,0 1 3,1 1 3,1 0 3,0 0 3),(-0.5 -0.5 3,-0.5 -0.4 3,-0.4 -0.4 3,-0.4 -0.5 3,-0.5 -0.5 3))",
	    "SRID=4326;MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
	    "SRID=4326;GEOMETRYCOLLECTION(POINT(0 1),POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0)),MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))))",
	    "POLYHEDRALSURFACE(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
	    "POLYHEDRALSURFACE(((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)),((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)))",
	    "TIN(((0 0,0 -1,-1 1,0 0)),((0 0,1 0,0 -1,0 0)))",
#if POSTGIS_SFCGAL_VERSION >= 10500
	    // Z/M Support
	    "POINTZM(1 2 3 4)",
	    "LINESTRINGM(0 0 1, 1 1 2, 2 2 3)",
	    "LINESTRINGZM(0 0 1 10, 1 1 2 20, 2 2 3 30)",
	    "TRIANGLEM((0 0 1, 1 1 2, 2 0 3, 0 0 1))",
	    "TRIANGLEZM((0 0 1 10, 1 1 2 20, 2 0 3 30, 0 0 1 10))",
	    "POLYGONM((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 1))",
	    "POLYGONZM((0 0 1 10, 0 1 2 20, 1 1 3 30, 1 0 4 40, 0 0 1 10))",
	    "MULTIPOINTM(0 0 1, 1 1 2, 2 2 3)",
	    "MULTIPOINTZM(0 0 1 10, 1 1 2 20, 2 2 3 30)",
	    "MULTILINESTRINGM((0 0 1, 1 1 2),(2 2 3, 3 3 4))",
	    "MULTILINESTRINGZM((0 0 1 10, 1 1 2 20),(2 2 3 30, 3 3 4 40))",
	    "MULTIPOLYGONM(((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 1)),((2 2 5, 2 3 6, 3 3 7, 3 2 8, 2 2 5)))",
	    "MULTIPOLYGONZM(((0 0 1 10, 0 1 2 20, 1 1 3 30, 1 0 4 40, 0 0 1 10)),((2 2 5 50, 2 3 6 60, 3 3 7 70, 3 2 8 80, 2 2 5 50)))",
	    "TINM(((0 0 1, 0 1 2, 1 0 3, 0 0 1)),((0 0 1, 1 0 3, 1 1 4, 0 0 1)))",
	    "TINZM(((0 0 1 10, 0 1 2 20, 1 0 3 30, 0 0 1 10)),((0 0 1 10, 1 0 3 30, 1 1 4 40, 0 0 1 10)))",
	    "POLYHEDRALSURFACEM(((0 0 1, 0 1 2, 1 1 3, 1 0 4, 0 0 1)),((0 0 1, 1 0 4, 1 -1 5, 0 -1 6, 0 0 1)))",
	    "POLYHEDRALSURFACEZM(((0 0 1 10, 0 1 2 20, 1 1 3 30, 1 0 4 40, 0 0 1 10)),((0 0 1 10, 1 0 4 40, 1 -1 5 50, 0 -1 6 60, 0 0 1 10)))",
	    "GEOMETRYCOLLECTIONM(LINESTRING M(-1 -1 3, 2 19 25, -4 20 15),POLYGONM((0 0 10, 2 19 25, -4 20 15, 0 0 10)))",
	    "GEOMETRYCOLLECTIONZM(LINESTRING ZM(-1 -1 3 4, 2 19 25 250, -4 20 15 150),POLYGONZM((0 0 10 100, 2 19 25 250, -4 20 15 150, 0 0 10 100)))",
#endif
	};
	char *expected_ewkt[] = {
	    "POINT(0 0.2)",
	    "LINESTRING(-1 -1,-1 2.5,2 2,2 -1)",
	    "TRIANGLE((0 0,-1 1,0 -1,0 0))",
	    "MULTIPOINT(0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9,0.9 0.9)",
	    "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))",
	    "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))",
	    "POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))",
	    "SRID=4326;POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))",
	    "SRID=4326;POLYGON((-1 -1 1,-1 2.5 1,2 2 2,2 -1 2,-1 -1 2),(0 0 1,0 1 1,1 1 1,1 0 2,0 0 2))",
	    "SRID=4326;POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))",
	    "SRID=100000;POLYGON((-1 -1 3,-1 2.5 3,2 2 3,2 -1 3,-1 -1 3),(0 0 3,0 1 3,1 1 3,1 0 3,0 0 3),(-0.5 -0.5 3,-0.5 -0.4 3,-0.4 -0.4 3,-0.4 -0.5 3,-0.5 -0.5 3))",
	    "SRID=4326;MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
	    "SRID=4326;GEOMETRYCOLLECTION(POINT(0 1),POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0)),MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))))",
	    "POLYHEDRALSURFACE(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
	    "POLYHEDRALSURFACE(((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)),((-1 -1 1,-1 2.5 1,2 2 1,2 -1 1,-1 -1 1),(0 0 1,0 1 1,1 1 1,1 0 1,0 0 1),(-0.5 -0.5 1,-0.5 -0.4 1,-0.4 -0.4 1,-0.4 -0.5 1,-0.5 -0.5 1)))",
	    "TIN(((0 0,0 -1,-1 1,0 0)),((0 0,1 0,0 -1,0 0)))",
#if POSTGIS_SFCGAL_VERSION >= 10500
	    // Z/M Support
	    "POINT(1 2 3 4)",
	    "LINESTRINGM(0 0 1,1 1 2,2 2 3)",
	    "LINESTRING(0 0 1 10,1 1 2 20,2 2 3 30)",
	    "TRIANGLEM((0 0 1,1 1 2,2 0 3,0 0 1))",
	    "TRIANGLE((0 0 1 10,1 1 2 20,2 0 3 30,0 0 1 10))",
	    "POLYGONM((0 0 1,0 1 2,1 1 3,1 0 4,0 0 1))",
	    "POLYGON((0 0 1 10,0 1 2 20,1 1 3 30,1 0 4 40,0 0 1 10))",
	    "MULTIPOINTM(0 0 1,1 1 2,2 2 3)",
	    "MULTIPOINT(0 0 1 10,1 1 2 20,2 2 3 30)",
	    "MULTILINESTRINGM((0 0 1,1 1 2),(2 2 3,3 3 4))",
	    "MULTILINESTRING((0 0 1 10,1 1 2 20),(2 2 3 30,3 3 4 40))",
	    "MULTIPOLYGONM(((0 0 1,0 1 2,1 1 3,1 0 4,0 0 1)),((2 2 5,2 3 6,3 3 7,3 2 8,2 2 5)))",
	    "MULTIPOLYGON(((0 0 1 10,0 1 2 20,1 1 3 30,1 0 4 40,0 0 1 10)),((2 2 5 50,2 3 6 60,3 3 7 70,3 2 8 80,2 2 5 50)))",
	    "TINM(((0 0 1,0 1 2,1 0 3,0 0 1)),((0 0 1,1 0 3,1 1 4,0 0 1)))",
	    "TIN(((0 0 1 10,0 1 2 20,1 0 3 30,0 0 1 10)),((0 0 1 10,1 0 3 30,1 1 4 40,0 0 1 10)))",
	    "POLYHEDRALSURFACEM(((0 0 1,0 1 2,1 1 3,1 0 4,0 0 1)),((0 0 1,1 0 4,1 -1 5,0 -1 6,0 0 1)))",
	    "POLYHEDRALSURFACE(((0 0 1 10,0 1 2 20,1 1 3 30,1 0 4 40,0 0 1 10)),((0 0 1 10,1 0 4 40,1 -1 5 50,0 -1 6 60,0 0 1 10)))",
	    "GEOMETRYCOLLECTIONM(LINESTRINGM(-1 -1 3,2 19 25,-4 20 15),POLYGONM((0 0 10,2 19 25,-4 20 15,0 0 10)))",
	    "GEOMETRYCOLLECTION(LINESTRING(-1 -1 3 4,2 19 25 250,-4 20 15 150),POLYGON((0 0 10 100,2 19 25 250,-4 20 15 150,0 0 10 100)))",
#endif
	};

	for (i = 0; i < (sizeof ewkt / sizeof(char *)); i++)
	{
		LWGEOM *geom_in, *geom_out;
		char *in_ewkt;
		char *out_ewkt;

		in_ewkt = ewkt[i];
		geom_in = lwgeom_from_wkt(in_ewkt, LW_PARSER_CHECK_NONE);
		geom_out = lwgeom_sfcgal_noop(geom_in);
		if (!geom_out)
		{
			fprintf(stderr, "\nNull return from lwgeom_sfcgal_noop with wkt:   %s\n", in_ewkt);
			lwgeom_free(geom_in);
			continue;
		}
		out_ewkt = lwgeom_to_ewkt(geom_out);
		if (strcmp(expected_ewkt[i], out_ewkt))
			fprintf(stderr, "\nTest case %zu failed:\nExp:\t%s\nObt:\t%s\n", i, expected_ewkt[i], out_ewkt);
		ASSERT_STRING_EQUAL(expected_ewkt[i], out_ewkt);
		lwfree(out_ewkt);
		lwgeom_free(geom_out);
		lwgeom_free(geom_in);
	}
}

/*
** Used by test harness to register the tests in this file.
*/
void sfcgal_suite_setup(void);
void
sfcgal_suite_setup(void)
{
	CU_pSuite suite = CU_add_suite("sfcgal", NULL, NULL);
	PG_ADD_TEST(suite, test_sfcgal_noop);
}
